/* retarget.c
 * Redirect printf and low-level write functions to USART1
 */

#include "usart.h"
#include "main.h"
#include <stdio.h>
#include <stdint.h>
#include <errno.h>

/* Some toolchains (older or non-POSIX) may not define standard errno codes like
    EINVAL or EIO. Provide fallback numeric definitions if missing. */
#ifndef EINVAL
#define EINVAL 22
#endif
#ifndef EIO
#define EIO 5
#endif

/* Universal blocking write used by different runtimes.
   Implements common entry points so printf is redirected to USART1
   for GCC (newlib), ARMCC/AC6 and other stdio implementations. */

int _write(int file, char *ptr, int len)
{
    if (ptr == NULL || len <= 0)
    {
        errno = EINVAL;
        return -1;
    }

    if (HAL_UART_Transmit(&huart1, (uint8_t *)ptr, len, HAL_MAX_DELAY) == HAL_OK)
    {
        return len;
    }

    errno = EIO;
    return -1;
}

/* fputc is used by some C libraries (and by semihosting replacements). */
int fputc(int ch, FILE *f)
{
    (void)f; /* suppress unused parameter warning */
    uint8_t c = (uint8_t)ch;
    if (HAL_UART_Transmit(&huart1, &c, 1, HAL_MAX_DELAY) != HAL_OK)
    {
        return EOF;
    }
    return ch;
}

/* Some toolchains or examples call __io_putchar or __stdout_putchar. Provide them. */
int __io_putchar(int ch)
{
    uint8_t c = (uint8_t)ch;
    if (HAL_UART_Transmit(&huart1, &c, 1, HAL_MAX_DELAY) != HAL_OK)
    {
        return EOF;
    }
    return ch;
}

int __stdout_putchar(int ch)
{
    uint8_t c = (uint8_t)ch;
    if (HAL_UART_Transmit(&huart1, &c, 1, HAL_MAX_DELAY) != HAL_OK)
    {
        return EOF;
    }
    return ch;
}

